package cn.edu.sgu.www.mhxysy.chain.login.impl;

import cn.edu.sgu.www.mhxysy.chain.login.UserLoginHandler;
import cn.edu.sgu.www.mhxysy.config.property.SystemSettingsProperties;
import cn.edu.sgu.www.mhxysy.dto.system.UserLoginDTO;
import cn.edu.sgu.www.mhxysy.util.UserUtils;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.Subject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * 登录处理-Shiro登录认证
 * @author 沐雨橙风ιε
 * @version 1.0
 */
@Component
public class ShiroLoginHandler implements UserLoginHandler {

    private Object params;
    private UserLoginHandler next;

    private final SystemSettingsProperties systemSettingsProperties;

    @Autowired
    public ShiroLoginHandler(SystemSettingsProperties systemSettingsProperties) {
        this.systemSettingsProperties = systemSettingsProperties;
    }

    @Override
    public void handle() {
        UserLoginDTO loginDTO = (UserLoginDTO) params;

        Subject subject = UserUtils.getSubject();

        // 当前用户没有登录才执行shiro登录认证操作
        if (!subject.isAuthenticated()) {
            // shiro登录认证
            UsernamePasswordToken token = new UsernamePasswordToken(loginDTO.getUsername(), loginDTO.getPassword());

            subject.login(token); // 登录

            /*
             * 设置session失效时间
             */
            // 获取session失效时间
            Long timeout = systemSettingsProperties.getSessionTimeout();

            /*
             * sessionTimeout的单位是秒
             * 为了防止这个时间过小，当设置的超时时间小于30分钟，按30分钟算
             */
            if (timeout < 1800) {
                timeout = 60 * 30L;
            }

            // 从Shiro中获取Session
            Session session = subject.getSession();

            /*
             * 设置Session的过期时间
             * session的过期时间的单位是毫秒，所以要乘以1000
             */
            session.setTimeout(timeout * 1000);

            if (next != null) {
                next.handle();
            }
        }
    }

    @Override
    public void setParams(Object params) {
        this.params = params;
    }

    @Override
    public void setNext(UserLoginHandler next) {
        this.next = next;
    }

}